/**
 * 
 */
package captor.crosscuttingdomainsystem.crosscuttinginfo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.bind.util.ValidationEventCollector;

import captor.lib.util.StringUtil;
import captor.modelsystem.Model;

/**
 * @author cafpj
 *
 */
public class CrosscuttingInfo implements ICrosscuttingInfo {

	/* (non-Javadoc)
	 * @see captor.crosscuttingdomainsystem.compatibilityinfo.ICompatibilityInfo#loadCompatibleDomains(java.lang.String)
	 */
	
	private Model model;
    
    public CrosscuttingInfo(Model model) {
        super();
        this.model = model;
    }
	
	public DomainInfo loadDomainInfo(String path) {
		// TODO Auto-generated method stub
		
		Unmarshaller u = null;
        JAXBContext jc = null;
        DomainInfo di = null;
        ValidationEventCollector vec = new ValidationEventCollector();
        
        try  {
            jc = JAXBContext.newInstance("captor.crosscuttingdomainsystem.crosscuttinginfo");
            u = jc.createUnmarshaller();
            
            u.setValidating(true);
            u.setEventHandler(vec);
        }
        catch(Exception e)  {
            model.getGui().getGuiView().setErrorView("Cannot load captor.crosscuttingdomainsystem.crosscuttinginfo XML instance: " + StringUtil.formatOutput(e.toString()) + "<br>");		
            throw new RuntimeException("Cannot load captor.crosscuttingdomainsystem.crosscuttinginfo XML instance: " + e);
        }
        
        try {
            FileInputStream is = new FileInputStream(path);            
            di = (DomainInfo)u.unmarshal(is);
            
        } catch (FileNotFoundException e2)  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\"><b>Cannot find file: </b></font>" + path + "<br>");
            throw new RuntimeException("Cannot find file: " + path);
            
        }catch ( UnmarshalException e4 )  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\"><b>Cannot parse the crosscutting information file: </b></font>" + path + "<br>");
            model.getGui().getGuiView().setErrorView("<br><b>Crosscutting information file invalid format: </b>" + StringUtil.formatOutput(e4.getMessage()) + "<br><br>");
            throw new RuntimeException("UnmarshalException: " + e4.getMessage());
            
	    } catch ( JAXBException e3 )  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\">Cannot parse the crosscutting information file.: </font>" + path + "<br><br>");
            model.getGui().getGuiView().setErrorView("Crosscutting information Metal-model invalid format: " + StringUtil.formatOutput(e3.getMessage()) + "<br><br>");
            throw new RuntimeException("Cannot find file: " + path);
            
        } catch (RuntimeException e1) {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\">Cannot parse the crosscutting compatibility information file.: </font>" + path + "<br><br>");
            model.getGui().getGuiView().setErrorView("Cannot validate crosscutting information meta-model file.<br><br>");
            throw new RuntimeException("Cannot validate crosscutting information meta-model file: " + path);
	    } 
        
        if( vec.hasEvents() ) {
            String space = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
            ValidationEvent []ve = vec.getEvents();
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\"><b>Meta-model invalid format:</b></font><br><br>");
            String spath = path.replace("\\\\", "\\");
            for ( int i = 0; i < ve.length; i++ )  {
                int severityNumber = ve[i].getSeverity();
                String severity = "";
                if ( severityNumber == ValidationEvent.ERROR )
                    severity = "ERROR";
                else if ( severityNumber == ValidationEvent.FATAL_ERROR )
                    severity = "FATAL ERROR";
                else if ( severityNumber == ValidationEvent.WARNING )
                    severity = "WARNING";
                
                if ( i > 0 )
                    model.getGui().getGuiView().setErrorView("<center><b>-----------------------------------------------------------------</b></center><br>");
                
                ValidationEventLocator locator = ve[i].getLocator(); 
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>File:</b> " + spath + "<br>");

                String msg = StringUtil.formatOutput(ve[i].getMessage());
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;<b>Description:</b> " + msg + "<br>");
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Severity:</b> " + severity + "<br><br>");
                
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Position:</b> <br>");
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Line Number:</b> " + locator.getLineNumber() + "<br>");
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;<b>Column Number:</b> " + locator.getColumnNumber() + "<br>");
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Node:</b> " + locator.getNode() + "<br>");
                model.getGui().getGuiView().setErrorView(space + "(" + i + ")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>URL:</b> " + locator.getURL() + "<br><br>");
            }
        } 
        return di;
	}
	
	public void writeDomainInfo(String path, DomainInfo domainInfo){
		
		Marshaller marshaller = null;
		ValidationEventCollector vec = new ValidationEventCollector();
		
		try 
		{
			JAXBContext jaxbContext = JAXBContext.newInstance("captor.crosscuttingdomainsystem.crosscuttinginfo");
			marshaller= jaxbContext.createMarshaller();
			marshaller.setEventHandler(vec);
			
		}
		catch(Exception e1)  {
            model.getGui().getGuiView().setErrorView("Cannot load captor.crosscuttingdomainsystem.crosscuttinginfo XML instance: " + StringUtil.formatOutput(e1.toString()) + "<br>");		
            throw new RuntimeException("Cannot load captor.crosscuttingdomainsystem.crosscuttinginfo XML instance: " + e1);
        }
		
		try 
		{
			File xmlDocument = new File(path);
			marshaller.marshal(domainInfo, new FileOutputStream(xmlDocument));
		}
		catch (FileNotFoundException e2)  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\"><b>Cannot find file: </b></font>" + path + "<br>");
            throw new RuntimeException("Cannot find file: " + path);
            
        }catch ( MarshalException e4 )  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\"><b>Cannot parse the crosscutting information file: </b></font>" + path + "<br>");
            model.getGui().getGuiView().setErrorView("<br><b>Crosscutting information file invalid format: </b>" + StringUtil.formatOutput(e4.getMessage()) + "<br><br>");
            throw new RuntimeException("MarshalException: " + e4.getMessage());
            
	    } catch ( JAXBException e3 )  {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\">Cannot parse the crosscutting information file.: </font>" + path + "<br><br>");
            model.getGui().getGuiView().setErrorView("Crosscutting information Metal-model invalid format: " + StringUtil.formatOutput(e3.getMessage()) + "<br><br>");
            throw new RuntimeException("Cannot find file: " + path);
            
        } catch (RuntimeException e1) {
            model.getGui().getGuiView().setErrorView("<font color=\"#FF0000\">Cannot parse the crosscutting compatibility information file.: </font>" + path + "<br><br>");
            model.getGui().getGuiView().setErrorView("Cannot validate crosscutting information meta-model file.<br><br>");
            throw new RuntimeException("Cannot validate crosscutting information meta-model file: " + path);
	    }		
	}
}
